<?php



namespace Feima\FlightLogProxy;
use Feima\FlightLogProxy\DatabaseProxy as DatabaseProxy;

function FLOG($str){
    //echo $str."\n";
}
/**
 * Created by PhpStorm.
 * User: jimmy
 * Date: 2017/12/7
 * Time: 下午4:53
 */
//数据库维护工具
class DatabaseMaintainer{

    private $dbProxy;
    private $config;
//    array(
//
//        /**********************        目标数据库      ********************/
//        "target_database_host" => '192.168.2.123',
//        "target_database_user" => 'root',
//        "target_database_password" => '123456',
//        "target_database_start_year"=>2015,
//
//        "source_database_host" => '192.168.2.123',
//        "source_database_user" => 'root',
//        "source_database_password" => '123456',
//        "source_database_name"=>"localdb",
//        "is_use_souce_db"=>true,
//    );
    private $dbYearsArray;
    private $sourceDbProxy;//源数据库



    //创建数据库
    /**
     * DatabaseMaintainer constructor.
     */
    public function __construct($config)
    {
        $this->config=$config;
        $this->dbYearsArray=array();
        $this->sourceDbProxy= $this->createPDO(array(
            "host"=>$this->config["source_database_host"],
            "dbname"=>$this->config["source_database_name"],
            "user_name"=>$this->config["source_database_user"],
            "password"=>$this->config["source_database_password"]
        ));
    }

    /**********************     公共静态方法      ********************/

    //获取数据库名字
    public static function getDatabaseName($curYear){
        return "db_flight_log_".$curYear;
    }

    //获取表名
    public static function getTableName(){
        return "flight_monitor_detail_log";
    }
    /**
     * @return array
     */
    public function getConfig()
    {
        return $this->config;
    }

    /**********************   提供数据库代理      ********************/

    /**
     * 获取源数据库的代理方法
     * @return mixed
     */
    public function getSourceDbProxy()
    {
        return $this->sourceDbProxy;
    }

    /**
     * 获取年的数据库连接
     * 如果对应数据库不存在,则创建连接
     * @param $year
     * @return DatabaseProxy
     */
    public function getYearDbProxy($year){

        if($year<$this->getConfig()["target_database_start_year"]){
            FLOG("年份小于开始年份");
            return false;
        }

        $databaseName=DatabaseMaintainer::getDatabaseName($year);
        if(array_key_exists($year,$this->dbYearsArray)){

            $dbProxy=$this->dbYearsArray[$year];
        }else{
            if(!$this->isDatabaseExist($databaseName))
            {
                //创建数据库
                $this->initYearDatabase($year);
            }

            $dbProxy= $this->createPDO(array(
                "host"=>$this->config["target_database_host"],
                "dbname"=>$databaseName,
                "user_name"=>$this->config["target_database_user"],
                "password"=>$this->config["target_database_password"]
            ));
            $this->dbYearsArray[$year]=$dbProxy;
        }
        return $dbProxy;
    }

    //数据库是否存在
    private function isDatabaseExist($databaseName){
        $result=$this->getDbProxy()->fetchOne("select count(*) total from information_schema.schemata where schema_name='$databaseName'");
        if(intval($result["total"])<=0){
            return false;
        }
        return true;
    }
    //数据库表是否存在
    private function isTableExist($databaseName,$tableName){
        $result=$this->getDbProxy()->fetchOne("SELECT table_name FROM information_schema.TABLES WHERE TABLE_SCHEMA='$databaseName' and table_name ='$tableName'");
        if(empty($result)){
            return false;
        }
        return true;
    }

    //获取维护代理连接
    private function getDbProxy(){
        if(!$this->dbProxy) {
            $this->dbProxy = $this->createConnection();
        }
        return $this->dbProxy;
    }

    private function closeDbProxy(){
        if($this->dbProxy){
            $this->dbProxy->close();
        }
        $this->dbProxy=null;
    }

    /**
     * 创建PDO连接
     * @param $config
     * array:
     *      host 连接地址,必填
     *      dbname 目标数据库,可选
     *      user_name 用户名
     *      password  密码
     * @return DatabaseProxy
     */
    private function createPDO($config){
        $host=$config["host"];
        if(array_key_exists("dbname",$config)){
            $dbName=$config["dbname"];
            $dsn="mysql:host=$host;dbname=$dbName";
        }else{
            $dsn="mysql:host=$host";
        }
        $db=new DatabaseProxy(array(
            "dsn"=>$dsn,
            "user_name"=>$config["user_name"],
            "password"=>$config["password"],
        ));
        return $db;
    }
    /**
     * 获取目标数据库的连接
     * @return DatabaseProxy
     */
    private function createConnection(){
        return $this->createPDO(array(
            "host"=>$this->config["target_database_host"],
            "user_name"=>$this->config["target_database_user"],
            "password"=>$this->config["target_database_password"],
        ));
    }

    private function initYearDatabase($startYear){
        $databaseName=$this->getDatabaseName($startYear);
        if(!$this->isDatabaseExist($databaseName)){
            //建立数据库
            if($this->getDbProxy()->execute("create database $databaseName")>0){
                FLOG("建立数据库:$databaseName 成功\n");
            }else{
                FLOG("建立数据库:$databaseName 失败\n");
            }
        }else{
            FLOG("数据库:$databaseName 已经存在");
        }
        //创建表
        $this->createTables($startYear);
    }
    //创建表
    private function createTables($curYear){
        $databaseName=$this->getDatabaseName($curYear);
        $tablename=DatabaseMaintainer::getTableName();
        $this->getDbProxy()->query("use $databaseName");
        FLOG("开始建立分表");
        $weekAppendSql="";
        for($i=8;$i<=366;){
            if($i!=8){
                $weekAppendSql.=",";
            }
            $weekAppendSql.="PARTITION p_flight_monitor_log$i VALUES LESS THAN ($i)";
            $i+=7;
        }
        $weekAppendSql.=",PARTITION p_flight_monitor_log_max VALUES LESS THAN MAXVALUE";

        $createTableSql="CREATE TABLE $tablename (
	id BIGINT NOT NULL AUTO_INCREMENT,
	local_id VARCHAR (32) NOT NULL,
	record_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ,
	message LONGTEXT NOT NULL,
	flight_mission_id INT (11) DEFAULT 0,
	created_str VARCHAR (32) NOT NULL,
	created_at datetime NOT NULL ,
	PRIMARY KEY (id, created_at),
	INDEX (flight_mission_id),
	INDEX (local_id)
) PARTITION BY RANGE (dayofyear(created_at))(
  $weekAppendSql
);";
        if($this->getDbProxy()->execute($createTableSql)>0){
            FLOG("建立分区表成功");
        }
    }
}



